package com.youlai.eng.common;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.object.SqlQuery;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 动态jpql/nativesql查询的实现类
 * 创建者
 * 创建时间  2018年3月8日
 */
@Repository
public class DynamicQueryImpl implements DynamicQuery {
    @PersistenceContext
    private EntityManager em;

    public EntityManager getEntityManager() {
        return em;
    }

    @Override
    public void save(Object entity) {
        em.persist(entity);
    }

    @Override
    public void update(Object entity) {
        em.merge(entity);
    }

    @Override
    public <T> void delete(Class<T> entityClass, Object entityid) {
        delete(entityClass, new Object[] { entityid });
    }

    @Override
    public <T> void delete(Class<T> entityClass, Object[] entityids) {
        for (Object id : entityids) {
            em.remove(em.getReference(entityClass, id));
        }
    }

    /**
     * hql 查询统计数据
     *
     * @author wangsong
     * @date 2019年9月10日
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> findStatis(Integer serverId, String channel, String startTime, String endTime) {
        // 拼接sql
        String hql = findStatisHql( serverId,  channel,startTime,endTime);
        // 查询数据
        jakarta.persistence.Query query = em.createQuery(hql);
        List<Object[]> objArray = query.getResultList(); // 根据返回的结果来定义接收数据类型(对象,集合,基本数据类型等)，我这里查询统计数据，所以 list<Object[]>  接收,下方有示例代码
        // 处理结果数据
        Map<String, Object> mapVal = new HashMap<>();
        List<Object> stepsList = new ArrayList<>();
        List<Object> conutList = new ArrayList<>();
        for (Object[] obj : objArray) {
            stepsList.add(obj[0]);
            conutList.add(obj[1]);
        }
        mapVal.put("stepsList", stepsList);
        mapVal.put("conutList", conutList);
        return mapVal;
    }

    /**
     * 拼接hql 查询语句 <br/>
     * hql =  select steps,count(*) from WastageRate where 1=1 and serverId=1 and channel='home' and time <= '2019-09-13' and time >= '2019-09-10 00:00:00' GROUP BY steps
     * @author wangsong
     * @date 2019年9月10日
     */
    public String findStatisHql(Integer serverId, String channel,String startTime,String endTime) {
        // 动态拼接sql
        String hql = "select steps,count(*) from WastageRate where 1=1";
        if (serverId != null && serverId != -1) {
            hql += " and serverId=" + serverId;
        }
        if (StringUtils.isNotEmpty(channel) && !channel.equals("-1")) {
            hql += " and channel='" + channel +"'";
        }
        if (StringUtils.isNotEmpty(startTime)) {
            hql += " and time >= '"+startTime +"'";
        }
        if (StringUtils.isNotEmpty(endTime)) {
            hql += " and time <= '" + endTime +"'";
        }
        hql += " GROUP BY steps";
        return hql;
    }



    private jakarta.persistence.Query createNativeQuery(String sql, Object... params) {
        jakarta.persistence.Query q = em.createNativeQuery(sql);
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                q.setParameter(i + 1, params[i]); // 与Hiberante不同,jpa query从位置1开始
            }
        }
        return q;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> nativeQueryList(String nativeSql, Object... params) {
        jakarta.persistence.Query q = createNativeQuery(nativeSql, params);
        q.unwrap(SqlQuery.class).setResultSetType(1);
        return q.getResultList();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> nativeQueryListModel(Class<T> resultClass,
                                            String nativeSql, Object... params) {
        jakarta.persistence.Query q = createNativeQuery(nativeSql, params);;
        q.unwrap(SqlQuery.class).setResultSetType(1);
        return q.getResultList();
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> nativeQueryListMap(String nativeSql, Object... params) {
        jakarta.persistence.Query q = createNativeQuery(nativeSql, params);
        q.unwrap(SqlQuery.class).setResultSetType(1); //setResultTransformer
        return q.getResultList();
    }

}
